home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks97
/
WarriorsProgress.sit
/
Warrior’s Progress
/
source code
/
Source
/
Libraries
/
Files
/
FileLocation.cp
< prev
next >
Wrap
Text File
|
1997-06-28
|
8KB
|
369 lines
// FileLocation.cp
#ifndef FileLocation_h
#include "FileLocation.h"
#endif
#ifndef PString_h
#include "PString.h"
#endif
#ifndef Str_h
#include "Str.h"
#endif
#ifndef Application_h
#include "Application.h"
#endif
#ifndef ProcessInfo_h
#include "ProcessInfo.h"
#endif
#ifndef FileNotFoundError_h
#include "FileNotFoundError.h"
#endif
#ifndef DirectoryNotFoundError_h
#include "DirectoryNotFoundError.h"
#endif
#ifndef DuplicateFileError_h
#include "DuplicateFileError.h"
#endif
#ifndef DirectoryFullError_h
#include "DirectoryFullError.h"
#endif
#ifndef DiskFullError_h
#include "DiskFullError.h"
#endif
#ifndef HardwareVolumeLockError_h
#include "HardwareVolumeLockError.h"
#endif
#ifndef SoftwareVolumeLockError_h
#include "SoftwareVolumeLockError.h"
#endif
#ifndef FileLockError_h
#include "FileLockError.h"
#endif
#ifndef FileBusyError_h
#include "FileBusyError.h"
#endif
#ifndef FilePermissionError_h
#include "FilePermissionError.h"
#endif
#ifndef CatInfo_h
#include "CatInfo.h"
#endif
FileLocation::FileLocation()
{
vRefNum = 0;
parID = 0;
name[0] = 0;
}
FileLocation::FileLocation( Directory directory,
ConstPString theName )
{
name[0] = 0;
SetParent( directory );
SetName( theName );
}
FileLocation::FileLocation( Directory directory )
{
name[0] = 0;
CatInfo info( directory );
*this = info.Location();
}
void FileLocation::Set( Directory directory,
ConstPString theName )
{
SetParent( directory );
SetName( theName );
}
void FileLocation::operator=( Directory directory )
{
CatInfo info( directory );
*this = info.Location();
}
void FileLocation::SetName( ConstPString newName )
{
PString( Data( name, sizeof(name) ) ) = newName;
}
void FileLocation::SetName( ConstPString base, uint32 number )
{
String31 newName;
String255 numeral;
NumToString( number, numeral );
if ( base.Length() + numeral.Length() + 1 <= 31 )
{
newName.SetLength( base.Length() + numeral.Length() + 1 );
newName.Head( base.Length() ) << base;
newName[ base.Length() ] = ' ';
newName.Tail( base.Length() + 1 ) << numeral;
}
else if ( base.Length() + numeral.Length() <= 31 )
{
newName.SetLength( base.Length() + numeral.Length() );
newName.Head( base.Length() ) << base;
newName.Tail( base.Length() ) << numeral;
}
else
{
uint32 baseAmount = 31 - numeral.Length() - 1;
static const uint8 elipsis = 0xc9;
newName.SetLength( 31 );
newName.Head( baseAmount ) << base;
newName[ baseAmount ] = elipsis;
newName.Tail( baseAmount + 1 ) << numeral;
}
SetName( newName );
}
Directory FileLocation::AsDirectory() const
{
return CatInfo( *this ).AsDirectory();
}
bool FileLocation::NameIsValid() const
{
ConstPString name( this->name );
if ( name.Length() == 0 )
return false;
if ( name.Length() > 31 )
return false;
if ( name[0] == '.' )
return false;
for ( uint32 i = 0; i < name.Length(); i++ )
if ( name[i] == ':' )
return false;
return true;
}
void FileLocation::SetToValidName( ConstPString start )
{
SetName( start );
SetToValidName();
}
void FileLocation::SetToValidName()
{
PString name( Data( this->name, sizeof(this->name) ) );
static const uint8 bullet = 0xA5;
if ( name.Length() == 0 )
{
name.SetLength( 1 );
name[0] = bullet;
}
if ( name.Length() > 31 )
name.SetLength( 31 );
if ( name[0] == '.' )
name[0] = bullet;
for ( uint32 i = 0; i < name.Length(); i++ )
if ( name[i] == ':' )
name[i] = '/';
Assert( NameIsValid() );
}
bool FileLocation::operator==( const FileLocation& r ) const
{
return vRefNum == r.vRefNum
&& parID == r.parID
&& EqualString( name, r.name, false, true );
}
void FileLocation::ThrowError( OSErr error )
{
if ( error == noErr )
return;
switch ( error )
{
case fnfErr: throw FileNotFoundError( error );
case dirNFErr: throw DirectoryNotFoundError( error );
case dupFNErr: throw DuplicateFileError( error );
case dirFulErr: throw DirectoryFullError( error );
case dskFulErr: throw DiskFullError( error );
case wPrErr: throw HardwareVolumeLockError( error );
case vLckdErr: throw SoftwareVolumeLockError( error );
case fLckdErr: throw FileLockError( error );
case fBsyErr: throw FileBusyError( error );
case afpAccessDenied: throw FilePermissionError( error );
}
throw FileError( error );
}
bool FileLocation::Exists() const
{
Assert( NameIsValid() );
String255 localName( name );
CInfoPBRec info;
info.hFileInfo.ioCompletion = 0;
info.hFileInfo.ioVRefNum = vRefNum;
info.hFileInfo.ioDirID = parID;
info.hFileInfo.ioNamePtr = localName;
info.hFileInfo.ioFVersNum = 0;
info.hFileInfo.ioFDirIndex = 0;
OSErr error = PBGetCatInfoSync( &info );
if ( error != noErr && error != fnfErr )
ThrowError( error );
return error == noErr;
}
void FileLocation::FindUnusedName()
{
if ( !Exists() )
return;
String31 baseName( name );
uint32 number = 1;
do
{
Assert( number < maxuint32 );
SetName( baseName, ++number );
}
while ( Exists() );
}
void FileLocation::CreateFile( FileType type,
FileSignature signature,
ScriptID script ) const
{
Assert( NameIsValid() );
ThrowError( FSpCreate( this,
signature.Signature(),
type.Type(),
script.ID() ) );
}
void FileLocation::CreateFile( FileType type,
ScriptID script ) const
{
CreateFile( type,
ProcessInfo::Application().Signature(),
script );
}
Directory FileLocation::CreateDirectory( ScriptID script ) const
{
Assert( NameIsValid() );
int32 directory;
ThrowError( FSpDirCreate( this, script.ID(), &directory ) );
return Directory( Volume(), DirectoryID::Make( directory ) );
}
void FileLocation::Delete() const
{
Assert( NameIsValid() );
ThrowError( FSpDelete( this ) );
}
void FileLocation::Lock() const
{
Assert( NameIsValid() );
ThrowError( FSpSetFLock( this ) );
}
void FileLocation::Unlock() const
{
Assert( NameIsValid() );
ThrowError( FSpRstFLock( this ) );
}
void FileLocation::MoveFrom( const FileLocation& source ) const
{
Assert( Volume() == source.Volume() );
Assert( *this != source );
Assert( NameIsValid() );
Assert( source.Exists() );
Assert( !Exists() );
if ( ParentID() == source.ParentID() )
ThrowError( FSpRename( &source, name ) );
else
ThrowError( FSpCatMove( &source, this ) );
}
void FileLocation::SwapWith( const FileLocation& source ) const
{
Assert( Volume() == source.Volume() );
Assert( *this != source );
Assert( NameIsValid() );
Assert( source.Exists() );
Assert( Exists() );
ThrowError( FSpExchangeFiles( this, &source ) );
}
void FileLocation::Up()
{
Assert( !IsRoot() );
if ( IsRoot() )
ThrowError( dirNFErr );
CatInfo info( Parent() );
*this = info.Location();
}
void FileLocation::Down( ConstPString child )
{
SetParent( AsDirectory() );
SetName( child );
}
void FileLocation::Sideways( ConstPString sibling )
{
SetName( sibling );
}
FileLocation FileLocation::Child( ConstPString child ) const
{
return FileLocation( AsDirectory(), child );
}
FileLocation FileLocation::Sibling( ConstPString sibling ) const
{
return FileLocation( Parent(), sibling );
}
DirectoryID FileLocation::GetDirectoryID() const
{
CatInfo info( *this );
Assert( info.IsDirectory() );
if ( !info.IsDirectory() )
ThrowError( afpObjectTypeErr );
return info.Directory().ID();
}
FileID FileLocation::GetFileID() const
{
CatInfo info( *this );
Assert( !info.IsDirectory() );
if ( info.IsDirectory() )
ThrowError( notAFileErr );
return info.File().ID();
}